{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Requirements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import unicodedata, string, re, random, time, math, torch, torch.nn as nn\n",
    "from torch.autograd import Variable\n",
    "from torch import optim\n",
    "import torch.nn.functional as F\n",
    "import keras, numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "from keras.preprocessing import sequence"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Loading data files\n",
    "\n",
    "The data for this project is a set of many thousands of English to French translation pairs.\n",
    "\n",
    "[This question on Open Data Stack Exchange](http://opendata.stackexchange.com/questions/3888/dataset-of-sentences-translated-into-many-languages) pointed me to the open translation site http://tatoeba.org/ which has downloads available at http://tatoeba.org/eng/downloads - and better yet, someone did the extra work of splitting language pairs into individual text files here: http://www.manythings.org/anki/\n",
    "\n",
    "The English to French pairs are too big to include in the repo, so download to `data/fra.txt` before continuing. The file is a tab separated list of translation pairs:\n",
    "\n",
    "```\n",
    "I am cold.    Je suis froid.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We'll need a unique index per word to use as the inputs and targets of the networks later. To keep track of all this we will use a helper class called `Lang` which has word &rarr; index (`word2index`) and index &rarr; word (`index2word`) dictionaries, as well as a count of each word `word2count` to use to later replace rare words."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "SOS_token = 0\n",
    "EOS_token = 1\n",
    "\n",
    "class Lang:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.word2index = {}\n",
    "        self.word2count = {}\n",
    "        self.index2word = {0: \"SOS\", 1: \"EOS\"}\n",
    "        self.n_words = 2 # Count SOS and EOS\n",
    "      \n",
    "    def addSentence(self, sentence):\n",
    "        for word in sentence.split(' '):\n",
    "            self.addWord(word)\n",
    "\n",
    "    def addWord(self, word):\n",
    "        if word not in self.word2index:\n",
    "            self.word2index[word] = self.n_words\n",
    "            self.word2count[word] = 1\n",
    "            self.index2word[self.n_words] = word\n",
    "            self.n_words += 1\n",
    "        else:\n",
    "            self.word2count[word] += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "The files are all in Unicode, to simplify we will turn Unicode characters to ASCII, make everything lowercase, and trim most punctuation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# Turn a Unicode string to plain ASCII, thanks to http://stackoverflow.com/a/518232/2809427\n",
    "def unicodeToAscii(s):\n",
    "    return ''.join(\n",
    "        c for c in unicodedata.normalize('NFD', s)\n",
    "        if unicodedata.category(c) != 'Mn'\n",
    "    )\n",
    "\n",
    "# Lowercase, trim, and remove non-letter characters\n",
    "def normalizeString(s):\n",
    "    s = unicodeToAscii(s.lower().strip())\n",
    "    s = re.sub(r\"([.!?])\", r\" \\1\", s)\n",
    "    s = re.sub(r\"[^a-zA-Z.!?]+\", r\" \", s)\n",
    "    return s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "To read the data file we will split the file into lines, and then split lines into pairs. The files are all English &rarr; Other Language, so if we want to translate from Other Language &rarr; English I added the `reverse` flag to reverse the pairs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def readLangs(lang1, lang2, pairs_file, reverse=False):\n",
    "    print(\"Reading lines...\")\n",
    "\n",
    "    # Read the file and split into lines\n",
    "    lines = open('data/%s' % (pairs_file)).read().strip().split('\\n')\n",
    "    \n",
    "    # Split every line into pairs and normalize\n",
    "    pairs = [[normalizeString(s) for s in l.split('\\t')] for l in lines]\n",
    "    \n",
    "    # Reverse pairs, make Lang instances\n",
    "    if reverse:\n",
    "        pairs = [list(reversed(p)) for p in pairs]\n",
    "        input_lang = Lang(lang2)\n",
    "        output_lang = Lang(lang1)\n",
    "    else:\n",
    "        input_lang = Lang(lang1)\n",
    "        output_lang = Lang(lang2)\n",
    "        \n",
    "    return input_lang, output_lang, pairs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Since there are a *lot* of example sentences and we want to train something quickly, we'll trim the data set to only relatively short and simple sentences. Here the maximum length is 10 words (that includes ending punctuation) and we're filtering to sentences that translate to the form \"I am\" or \"He is\" etc. (accounting for apostrophes replaced earlier)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "MAX_LENGTH = 10\n",
    "\n",
    "eng_prefixes = (\n",
    "    \"i am \", \"i m \",\n",
    "    \"he is\", \"he s \",\n",
    "    \"she is\", \"she s\",\n",
    "    \"you are\", \"you re \",\n",
    "    \"we are\", \"we re \",\n",
    "    \"they are\", \"they re \"\n",
    ")\n",
    "\n",
    "def filterPair(p):\n",
    "    return len(p[0].split(' ')) < MAX_LENGTH and \\\n",
    "        len(p[1].split(' ')) < MAX_LENGTH and \\\n",
    "        p[1].startswith(eng_prefixes)\n",
    "\n",
    "def filterPairs(pairs):\n",
    "    return [pair for pair in pairs if filterPair(pair)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "The full process for preparing the data is:\n",
    "\n",
    "* Read text file and split into lines, split lines into pairs\n",
    "* Normalize text, filter by length and content\n",
    "* Make word lists from sentences in pairs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reading lines...\n",
      "Read 135842 sentence pairs\n",
      "Trimmed to 10853 sentence pairs\n",
      "Counting words...\n",
      "Counted words:\n",
      "fra 4489\n",
      "eng 2925\n",
      "['il est respecte par tout le monde .', 'he is respected by everyone .']\n"
     ]
    }
   ],
   "source": [
    "def prepareData(lang1, lang2, pairs_file, reverse=False):\n",
    "    input_lang, output_lang, pairs = readLangs(lang1, lang2, pairs_file, reverse)\n",
    "    print(\"Read %s sentence pairs\" % len(pairs))\n",
    "    pairs = filterPairs(pairs)\n",
    "    print(\"Trimmed to %s sentence pairs\" % len(pairs))\n",
    "    print(\"Counting words...\")\n",
    "    for pair in pairs:\n",
    "        input_lang.addSentence(pair[0])\n",
    "        output_lang.addSentence(pair[1])\n",
    "    print(\"Counted words:\")\n",
    "    print(input_lang.name, input_lang.n_words)\n",
    "    print(output_lang.name, output_lang.n_words)\n",
    "    return input_lang, output_lang, pairs\n",
    "\n",
    "input_lang, output_lang, pairs = prepareData('eng', 'fra', 'fra.txt', True)\n",
    "print(random.choice(pairs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def indexesFromSentence(lang, sentence):\n",
    "    return [lang.word2index[word] for word in sentence.split(' ')]+[EOS_token]\n",
    "\n",
    "def variableFromSentence(lang, sentence):\n",
    "    indexes = indexesFromSentence(lang, sentence)\n",
    "    return Variable(torch.LongTensor(indexes).unsqueeze(0))\n",
    "\n",
    "def variablesFromPair(pair):\n",
    "    input_variable = variableFromSentence(input_lang, pair[0])\n",
    "    target_variable = variableFromSentence(output_lang, pair[1])\n",
    "    return (input_variable, target_variable)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def index_and_pad(lang, dat):\n",
    "    return sequence.pad_sequences([indexesFromSentence(lang, s) \n",
    "                                  for s in dat], padding='post').astype(np.int64)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "fra, eng = list(zip(*pairs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "fra = index_and_pad(input_lang, fra)\n",
    "eng = index_and_pad(output_lang, eng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def get_batch(x, y, batch_size=16):\n",
    "    idxs = np.random.permutation(len(x))[:batch_size]\n",
    "    return x[idxs], y[idxs]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "heading_collapsed": true
   },
   "source": [
    "## The Encoder\n",
    "\n",
    "The encoder of a seq2seq network is a RNN that outputs some value for every word from the input sentence. For every input word the encoder outputs a vector and a hidden state, and uses the hidden state for the next input word."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "class EncoderRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, n_layers=1):\n",
    "        super(EncoderRNN, self).__init__()\n",
    "        self.hidden_size = hidden_size\n",
    "        self.embedding = nn.Embedding(input_size, hidden_size)\n",
    "        self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True, num_layers=n_layers)\n",
    "        \n",
    "    def forward(self, input, hidden):\n",
    "        output, hidden = self.gru(self.embedding(input), hidden)\n",
    "        return output, hidden\n",
    "\n",
    "    # TODO: other inits\n",
    "    def initHidden(self, batch_size):\n",
    "        return Variable(torch.zeros(1, batch_size, self.hidden_size))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "heading_collapsed": true
   },
   "source": [
    "## Simple Decoder\n",
    "\n",
    "In the simplest seq2seq decoder we use only last output of the encoder. This last output is sometimes called the *context vector* as it encodes context from the entire sequence. This context vector is used as the initial hidden state of the decoder.\n",
    "\n",
    "At every step of decoding, the decoder is given an input token and hidden state. The initial input token is the start-of-string `<SOS>` token, and the first hidden state is the context vector (the encoder's last hidden state)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "class DecoderRNN(nn.Module):\n",
    "    def __init__(self, hidden_size, output_size, n_layers=1):\n",
    "        super(DecoderRNN, self).__init__()\n",
    "        self.embedding = nn.Embedding(output_size, hidden_size)\n",
    "        self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True, num_layers=n_layers)\n",
    "        # TODO use transpose of embedding\n",
    "        self.out = nn.Linear(hidden_size, output_size)\n",
    "        self.sm = nn.LogSoftmax()\n",
    "        \n",
    "    def forward(self, input, hidden):\n",
    "        emb = self.embedding(input).unsqueeze(1)\n",
    "        # NB: Removed relu\n",
    "        res, hidden = self.gru(emb, hidden)\n",
    "        output = self.sm(self.out(res[:,0]))\n",
    "        return output, hidden"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "heading_collapsed": true
   },
   "source": [
    "## Attention Decoder"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "If only the context vector is passed betweeen the encoder and decoder, that single vector carries the burden of encoding the entire sentence. \n",
    "\n",
    "Attention allows the decoder network to \"focus\" on a different part of the encoder's outputs for every step of the decoder's own outputs. First we calculate a set of *attention weights*. These will be multiplied by the encoder output vectors to create a weighted combination. The result (called `attn_applied` in the code) should contain information about that specific part of the input sequence, and thus help the decoder choose the right output words.\n",
    "\n",
    "![](https://i.imgur.com/1152PYf.png)\n",
    "\n",
    "Calculating the attention weights is done with another feed-forward layer `attn`, using the decoder's input and hidden state as inputs. Because there are sentences of all sizes in the training data, to actually create and train this layer we have to choose a maximum sentence length (input length, for encoder outputs) that it can apply to. Sentences of the maximum length will use all the attention weights, while shorter sentences will only use the first few.\n",
    "\n",
    "![](images/attention-decoder-network.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "outputs": [],
   "source": [
    "class AttnDecoderRNN(nn.Module):\n",
    "    def __init__(self, hidden_size, output_size, n_layers=1, dropout_p=0.1, max_length=MAX_LENGTH):\n",
    "        super(AttnDecoderRNN, self).__init__()\n",
    "        self.hidden_size = hidden_size\n",
    "        self.output_size = output_size\n",
    "        self.n_layers = n_layers\n",
    "        self.dropout_p = dropout_p\n",
    "        self.max_length = max_length\n",
    "        \n",
    "        self.embedding = nn.Embedding(self.output_size, self.hidden_size)\n",
    "        self.attn = nn.Linear(self.hidden_size * 2, self.max_length)\n",
    "        self.attn_combine = nn.Linear(self.hidden_size * 2, self.hidden_size)\n",
    "        self.dropout = nn.Dropout(self.dropout_p)\n",
    "        self.gru = nn.GRU(self.hidden_size, self.hidden_size)\n",
    "        self.out = nn.Linear(self.hidden_size, self.output_size)\n",
    "        \n",
    "    def forward(self, input, hidden, encoder_output, encoder_outputs):\n",
    "        embedded = self.embedding(input).view(1, 1, -1)\n",
    "        embedded = self.dropout(embedded)\n",
    "        \n",
    "        attn_weights = F.softmax(self.attn(torch.cat((embedded[0], hidden[0]), 1)))\n",
    "        attn_applied = torch.bmm(attn_weights.unsqueeze(0), encoder_outputs.unsqueeze(0))\n",
    "        \n",
    "        output = torch.cat((embedded[0], attn_applied[0]), 1)\n",
    "        output = self.attn_combine(output).unsqueeze(0)\n",
    "\n",
    "        for i in range(self.n_layers):\n",
    "            output = F.relu(output)\n",
    "            output, hidden = self.gru(output, hidden)\n",
    "\n",
    "        output = F.log_softmax(self.out(output[0]))\n",
    "        return output, hidden, attn_weights\n",
    "\n",
    "    def initHidden(self):\n",
    "        return Variable(torch.zeros(1, 1, self.hidden_size))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true,
    "hidden": true
   },
   "source": [
    "*Note:* There are other forms of attention that work around the length limitation by using a  relative position approach. Read about \"local attention\" in [Effective Approaches to Attention-based Neural Machine Translation](https://arxiv.org/abs/1508.04025)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Training\n",
    "\n",
    "To train we run the input sentence through the encoder, and keep track of every output and the latest hidden state. Then the decoder is given the `<SOS>` token as its first input, and the last hidden state of the decoder as its first hidden state.\n",
    "\n",
    "\"Teacher forcing\" is the concept of using the real target outputs as each next input, instead of using the decoder's guess as the next input. Using teacher forcing causes it to converge faster but [when the trained network is exploited, it may exhibit instability](http://minds.jacobs-university.de/sites/default/files/uploads/papers/ESNTutorialRev.pdf)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def train(input_variable, target_variable, encoder, decoder, \n",
    "          encoder_optimizer, decoder_optimizer, criterion, max_length=MAX_LENGTH):\n",
    "    batch_size, input_length = input_variable.size()\n",
    "    target_length = target_variable.size()[1]\n",
    "    encoder_hidden = encoder.initHidden(batch_size).cuda()\n",
    "    encoder_optimizer.zero_grad()\n",
    "    decoder_optimizer.zero_grad()\n",
    "    loss = 0\n",
    "\n",
    "    encoder_output, encoder_hidden = encoder(input_variable, encoder_hidden)\n",
    "    decoder_input = Variable(torch.LongTensor([SOS_token]*batch_size)).cuda()\n",
    "    decoder_hidden = encoder_hidden\n",
    "\n",
    "    for di in range(target_length):\n",
    "        decoder_output, decoder_hidden = decoder(decoder_input, decoder_hidden)          \n",
    "                #, encoder_output, encoder_outputs)\n",
    "        targ = target_variable[:, di]\n",
    "#         print(decoder_output.size(), targ.size(), target_variable.size())\n",
    "        loss += criterion(decoder_output, targ)\n",
    "        decoder_input = targ\n",
    "\n",
    "    loss.backward()\n",
    "    encoder_optimizer.step()\n",
    "    decoder_optimizer.step()\n",
    "    return loss.data[0] / target_length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def asMinutes(s):\n",
    "    m = math.floor(s / 60)\n",
    "    s -= m * 60\n",
    "    return '%dm %ds' % (m, s)\n",
    "\n",
    "def timeSince(since, percent):\n",
    "    now = time.time()\n",
    "    s = now - since\n",
    "    es = s / (percent)\n",
    "    rs = es - s\n",
    "    return '%s (- %s)' % (asMinutes(s), asMinutes(rs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def trainEpochs(encoder, decoder, n_epochs, print_every=1000, plot_every=100, \n",
    "                learning_rate=0.01):\n",
    "    start = time.time()\n",
    "    plot_losses = []\n",
    "    print_loss_total = 0 # Reset every print_every\n",
    "    plot_loss_total = 0 # Reset every plot_every\n",
    "    \n",
    "    encoder_optimizer = optim.RMSprop(encoder.parameters(), lr=learning_rate)\n",
    "    decoder_optimizer = optim.RMSprop(decoder.parameters(), lr=learning_rate)\n",
    "    criterion = nn.NLLLoss().cuda()\n",
    "    \n",
    "    for epoch in range(1, n_epochs + 1):\n",
    "        training_batch = get_batch(fra, eng)\n",
    "        input_variable = Variable(torch.LongTensor(training_batch[0])).cuda()\n",
    "        target_variable = Variable(torch.LongTensor(training_batch[1])).cuda()\n",
    "        loss = train(input_variable, target_variable, encoder, decoder, encoder_optimizer, \n",
    "                     decoder_optimizer, criterion)\n",
    "        print_loss_total += loss\n",
    "        plot_loss_total += loss\n",
    "\n",
    "        if epoch % print_every == 0:\n",
    "            print_loss_avg = print_loss_total / print_every\n",
    "            print_loss_total = 0\n",
    "            print('%s (%d %d%%) %.4f' % (timeSince(start, epoch / n_epochs), epoch, \n",
    "                                         epoch / n_epochs * 100, print_loss_avg))\n",
    "        \n",
    "        if epoch % plot_every == 0:\n",
    "            plot_loss_avg = plot_loss_total / plot_every\n",
    "            plot_losses.append(plot_loss_avg)\n",
    "            plot_loss_total = 0\n",
    "    \n",
    "    showPlot(plot_losses)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "### Attention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# TODO: Make this change during training\n",
    "teacher_forcing_ratio = 0.5\n",
    "\n",
    "def attn_train(input_variable, target_variable, encoder, decoder, encoder_optimizer, \n",
    "          decoder_optimizer, criterion, max_length=MAX_LENGTH):\n",
    "    encoder_hidden = encoder.initHidden()\n",
    "\n",
    "    encoder_optimizer.zero_grad()\n",
    "    decoder_optimizer.zero_grad()\n",
    "\n",
    "    input_length = input_variable.size()[0]\n",
    "    target_length = target_variable.size()[0]\n",
    "    encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size))\n",
    "    loss = 0\n",
    "\n",
    "    for ei in range(input_length):\n",
    "        encoder_output, encoder_hidden = encoder(input_variable[ei], encoder_hidden)\n",
    "        encoder_outputs[ei] = encoder_output[0][0]\n",
    "\n",
    "    decoder_input = Variable(torch.LongTensor([[SOS_token]]))\n",
    "    decoder_hidden = encoder_hidden\n",
    "\n",
    "    use_teacher_forcing = True if random.random() < teacher_forcing_ratio else False\n",
    "    \n",
    "    if use_teacher_forcing:\n",
    "        # Teacher forcing: Feed the target as the next input\n",
    "        for di in range(target_length):\n",
    "            decoder_output, decoder_hidden, decoder_attention = decoder(\n",
    "                decoder_input, decoder_hidden, encoder_output, encoder_outputs)\n",
    "            loss += criterion(decoder_output[0], target_variable[di])\n",
    "            decoder_input = target_variable[di] # Teacher forcing\n",
    "\n",
    "    else:\n",
    "        # Without teacher forcing: use its own predictions as the next input\n",
    "        for di in range(target_length):\n",
    "            decoder_output, decoder_hidden, decoder_attention = decoder(\n",
    "                decoder_input, decoder_hidden, encoder_output, encoder_outputs)\n",
    "            topv, topi = decoder_output.data.topk(1)\n",
    "            ni = topi[0][0]\n",
    "            decoder_input = Variable(torch.LongTensor([[ni]]))\n",
    "            loss += criterion(decoder_output[0], target_variable[di])\n",
    "            if ni == EOS_token:\n",
    "                break\n",
    "\n",
    "    loss.backward()\n",
    "    \n",
    "    encoder_optimizer.step()\n",
    "    decoder_optimizer.step()\n",
    "    \n",
    "    return loss.data[0] / target_length"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Plotting results\n",
    "\n",
    "Plotting is done with matplotlib, using the array of loss values `plot_losses` saved while training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as ticker\n",
    "import numpy as np\n",
    "%matplotlib inline\n",
    "\n",
    "def showPlot(points):\n",
    "    plt.figure()\n",
    "    fig, ax = plt.subplots()\n",
    "    loc = ticker.MultipleLocator(base=0.2) # this locator puts ticks at regular intervals\n",
    "    ax.yaxis.set_major_locator(loc)\n",
    "    plt.plot(points)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Evaluation\n",
    "\n",
    "Evaluation is mostly the same as training, but there are no targets so we simply feed the decoder's predictions back to itself for each step. Every time it predicts a word we add it to the output string, and if it predicts the EOS token we stop there. We also store the decoder's attention outputs for display later."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def evaluate(encoder, decoder, sentence, max_length=MAX_LENGTH):\n",
    "    input_variable = variableFromSentence(input_lang, sentence).cuda()\n",
    "    input_length = input_variable.size()[0]\n",
    "    encoder_hidden = encoder.initHidden(1).cuda()\n",
    "    encoder_output, encoder_hidden = encoder(input_variable, encoder_hidden)\n",
    "\n",
    "    decoder_input = Variable(torch.LongTensor([SOS_token])).cuda()\n",
    "    decoder_hidden = encoder_hidden\n",
    "    \n",
    "    decoded_words = []\n",
    "#     decoder_attentions = torch.zeros(max_length, max_length)\n",
    "    \n",
    "    for di in range(max_length):\n",
    "#         decoder_output, decoder_hidden, decoder_attention = decoder(\n",
    "        decoder_output, decoder_hidden = decoder(decoder_input, decoder_hidden)\n",
    "        #, encoder_output, encoder_outputs)\n",
    "#         decoder_attentions[di] = decoder_attention.data\n",
    "        topv, topi = decoder_output.data.topk(1)\n",
    "        ni = topi[0][0]\n",
    "        if ni == EOS_token:\n",
    "            decoded_words.append('<EOS>')\n",
    "            break\n",
    "        else:\n",
    "            decoded_words.append(output_lang.index2word[ni])\n",
    "        decoder_input = Variable(torch.LongTensor([ni])).cuda()\n",
    "    \n",
    "    return decoded_words,0#, decoder_attentions[:di+1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def evaluateRandomly(encoder, decoder, n=10):\n",
    "    for i in range(n):\n",
    "        pair = random.choice(pairs)\n",
    "        print('>', pair[0])\n",
    "        print('=', pair[1])\n",
    "        output_words, attentions = evaluate(encoder, decoder, pair[0])\n",
    "        output_sentence = ' '.join(output_words)\n",
    "        print('<', output_sentence)\n",
    "        print('')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Training and Evaluating\n",
    "\n",
    "*Note:* If you run this notebook you can train, interrupt the kernel, evaluate, and continue training later. Comment out the lines where the encoder and decoder are initialized and run `trainEpochs` again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "#TODO:\n",
    "# - Test set\n",
    "# - random teacher forcing\n",
    "# - attention\n",
    "# - multi layers\n",
    "# - bidirectional encoding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "hidden_size = 256\n",
    "encoder1 = EncoderRNN(input_lang.n_words, hidden_size).cuda()\n",
    "attn_decoder1 = DecoderRNN(hidden_size, output_lang.n_words).cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0m 10s (- 5m 13s) (500 3%) 1.6385\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m----------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m              Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-30-4c17a8fe9278>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtrainEpochs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mencoder1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mattn_decoder1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m15000\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprint_every\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m500\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlearning_rate\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.005\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m<ipython-input-23-8db8bf0fae53>\u001b[0m in \u001b[0;36mtrainEpochs\u001b[0;34m(encoder, decoder, n_epochs, print_every, plot_every, learning_rate)\u001b[0m\n\u001b[1;32m     15\u001b[0m         \u001b[0mtarget_variable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mVariable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLongTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtraining_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     16\u001b[0m         loss = train(input_variable, target_variable, encoder, decoder, encoder_optimizer, \n\u001b[0;32m---> 17\u001b[0;31m                      decoder_optimizer, criterion)\n\u001b[0m\u001b[1;32m     18\u001b[0m         \u001b[0mprint_loss_total\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     19\u001b[0m         \u001b[0mplot_loss_total\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-21-f9dfc356042f>\u001b[0m in \u001b[0;36mtrain\u001b[0;34m(input_variable, target_variable, encoder, decoder, encoder_optimizer, decoder_optimizer, criterion, max_length)\u001b[0m\n\u001b[1;32m     20\u001b[0m         \u001b[0mdecoder_input\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtarg\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 22\u001b[0;31m     \u001b[0mloss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     23\u001b[0m     \u001b[0mencoder_optimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     24\u001b[0m     \u001b[0mdecoder_optimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/jhoward/anaconda3/lib/python3.5/site-packages/torch/autograd/variable.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, gradient, retain_variables)\u001b[0m\n\u001b[1;32m    156\u001b[0m                     'or with gradient w.r.t. the variable')\n\u001b[1;32m    157\u001b[0m             \u001b[0mgradient\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnew\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize_as_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfill_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 158\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_execution_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_backward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mgradient\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_variables\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    159\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    160\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mregister_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/jhoward/anaconda3/lib/python3.5/site-packages/torch/autograd/function.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, *gradients)\u001b[0m\n\u001b[1;32m    208\u001b[0m         \u001b[0mnested_gradients\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_unflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgradients\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_nested_output\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    209\u001b[0m         \u001b[0;32mdel\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_nested_output\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 210\u001b[0;31m         \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward_extended\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mnested_gradients\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    211\u001b[0m         \u001b[0;32mdel\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_to_save_nested\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    212\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_iter_None_tensors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/jhoward/anaconda3/lib/python3.5/site-packages/torch/nn/_functions/rnn.py\u001b[0m in \u001b[0;36mbackward_extended\u001b[0;34m(self, grad_output, grad_hy)\u001b[0m\n\u001b[1;32m    205\u001b[0m             \u001b[0mgrad_hy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    206\u001b[0m             \u001b[0mgrad_input\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 207\u001b[0;31m             grad_hx)\n\u001b[0m\u001b[1;32m    208\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    209\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneeds_input_grad\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/home/jhoward/anaconda3/lib/python3.5/site-packages/torch/backends/cudnn/rnn.py\u001b[0m in \u001b[0;36mbackward_grad\u001b[0;34m(fn, input, hx, weight, output, grad_output, grad_hy, grad_input, grad_hx)\u001b[0m\n\u001b[1;32m    368\u001b[0m             \u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcx_desc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mctypes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc_void_p\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdcx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata_ptr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcx\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    369\u001b[0m             \u001b[0mctypes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc_void_p\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mworkspace\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata_ptr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mworkspace\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 370\u001b[0;31m             \u001b[0mctypes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc_void_p\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreserve\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata_ptr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreserve\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    371\u001b[0m         ))\n\u001b[1;32m    372\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "trainEpochs(encoder1, attn_decoder1, 15000, print_every=500, learning_rate=0.005)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "> c est un ecrivain talentueux .\n",
      "= he s a talented writer .\n",
      "< he s a talented writer . <EOS>\n",
      "\n",
      "> en realite il n est pas l impresario .\n",
      "= he is actually not the manager .\n",
      "< he is actually not the manager . <EOS>\n",
      "\n",
      "> vous etes le dernier espoir de l humanite .\n",
      "= you re the last hope for humanity .\n",
      "< you re the last hope for humanity . <EOS>\n",
      "\n",
      "> je me fais des soucis pour sa securite .\n",
      "= i am concerned for her safety .\n",
      "< i m concerned with my new light . <EOS>\n",
      "\n",
      "> je ne vais pas mentir .\n",
      "= i m not going to lie .\n",
      "< i m not going to do my not gonna up\n",
      "\n",
      "> vous etes fort courageuse .\n",
      "= you re very brave .\n",
      "< you re very brave . <EOS>\n",
      "\n",
      "> nous sommes contents que vous soyez la .\n",
      "= we re glad you re here .\n",
      "< we re glad you re here . <EOS>\n",
      "\n",
      "> vous etes incroyablement talentueuses .\n",
      "= you re incredibly talented .\n",
      "< you re incredibly talented . <EOS>\n",
      "\n",
      "> je suis a court d idees .\n",
      "= i m out of ideas .\n",
      "< i m the tallest one of them . <EOS>\n",
      "\n",
      "> tu le fais comme il faut .\n",
      "= you re doing it right .\n",
      "< you re doing it right . <EOS>\n",
      "\n"
     ]
    }
   ],
   "source": [
    "evaluateRandomly(encoder1, attn_decoder1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Visualizing Attention\n",
    "\n",
    "A useful property of the attention mechanism is its highly interpretable outputs. Because it is used to weight specific encoder outputs of the input sequence, we can imagine looking where the network is focused most at each time step.\n",
    "\n",
    "You could simply run `plt.matshow(attentions)` to see attention output displayed as a matrix, with the columns being input steps and rows being output steps:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NOTE: This only works when using the attentional decoder, if you've been following the notebook to this point you are using the standard decoder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x11338b208>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\ncQIAtPL/ANFh73/w9PsAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x111deafd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "output_words, attentions = evaluate(encoder1, attn_decoder1, \"je suis trop froid .\")\n",
    "plt.matshow(attentions.numpy())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "For a better viewing experience we will do the extra work of adding axes and labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def showAttention(input_sentence, output_words, attentions):\n",
    "    # Set up figure with colorbar\n",
    "    fig = plt.figure()\n",
    "    ax = fig.add_subplot(111)\n",
    "    cax = ax.matshow(attentions.numpy(), cmap='bone')\n",
    "    fig.colorbar(cax)\n",
    "\n",
    "    # Set up axes\n",
    "    ax.set_xticklabels([''] + input_sentence.split(' ') + ['<EOS>'], rotation=90)\n",
    "    ax.set_yticklabels([''] + output_words)\n",
    "\n",
    "    # Show label at every tick\n",
    "    ax.xaxis.set_major_locator(ticker.MultipleLocator(1))\n",
    "    ax.yaxis.set_major_locator(ticker.MultipleLocator(1))\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "def evaluateAndShowAttention(input_sentence):\n",
    "    output_words, attentions = evaluate(encoder1, attn_decoder1, input_sentence)\n",
    "    print('input =', input_sentence)\n",
    "    print('output =', ' '.join(output_words))\n",
    "    showAttention(input_sentence, output_words, attentions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input = elle a cinq ans de moins que moi .\n",
      "output = she s five years younger than me . <EOS>\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1175fa748>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluateAndShowAttention(\"elle a cinq ans de moins que moi .\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input = elle est trop petit .\n",
      "output = she is never short . <EOS>\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x112806940>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluateAndShowAttention(\"elle est trop petit .\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input = je ne crains pas de mourir .\n",
      "output = i m not scared of that . <EOS>\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nYZpAqz+FEC4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11280bf60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluateAndShowAttention(\"je ne crains pas de mourir .\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input = c est un jeune directeur plein de talent .\n",
      "output = he s a talented young man . <EOS>\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11676f630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluateAndShowAttention(\"c est un jeune directeur plein de talent .\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "source": [
    "* Replace the embedding pre-trained word embeddings such as word2vec or GloVe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
